﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SimpleJson;
using Common;
namespace Dropbox
{
    public partial class DropboxDelta : BindableBaseCommon
    {
        private bool _HasMore;
        private string _Cursor;
        private bool _Reset;
        protected string originalString;
        DateTime? _LastDeltaRetrieved;

        public static DropboxDelta Load(String json)
        {
            var result = new DropboxDelta();
            result.originalString = json;
            Debug.WriteLine("Delta JSON:\n" + json);
            JsonObject jsonObj;
            try
            {

                jsonObj = (JsonObject)SimpleJson.SimpleJson.DeserializeObject(json);
            }
            catch (Exception ex)
            {
                return result;
            }

            if (jsonObj.ContainsKey("reset"))
            {
                result.Reset = jsonObj["reset"].ToString().ToLower() == "true";
            }
            if (jsonObj.ContainsKey("cursor"))
            {
                result.Cursor = jsonObj["cursor"].ToString();
            }
            if (jsonObj.ContainsKey("has_more"))
            {
                result.HasMore = jsonObj["has_more"].ToString().ToLower() == "true";
            }
            result.LastDeltaRetrieved = DateTime.Now;
            if (jsonObj.ContainsKey("dateTimeString"))
            {
                DateTime outDateTime;
                if (DateTime.TryParse(jsonObj["dateTimeString"].ToString(), out outDateTime))
                    result.LastDeltaRetrieved = outDateTime;
            }

            result.Entries = new Dictionary<String, DropboxFileSystemItem>();
            if (jsonObj.ContainsKey("entries"))
            {
                var entries = (JsonArray)jsonObj["entries"];
                foreach (JsonArray entry in entries)
                {
                    var key = (String)entry[0];
                    var value = (entry[1] != null) ? entry[1].ToString() : "";
                    if (String.IsNullOrEmpty(value) || value == "null")
                        result.Entries[key] = null;
                    else
                        result.Entries[key] = DropboxFileSystemItem.Load(value);
                }
            }
            result.generateNewJsonString();
            return result;
        }

        public override string ToString()
        {
            return originalString;
        }

        public bool Reset
        {
            get
            {
                return _Reset;
            }
            set
            {
                this.SetProperty(ref this._Reset, value);
            }
        }

        public string Cursor
        {
            get
            {
                return _Cursor;
            }
            set
            {
                this.SetProperty(ref this._Cursor, value);
            }
        }

        public bool HasMore
        {
            get
            {
                return _HasMore;
            }
            set
            {
                this.SetProperty(ref this._HasMore, value);
            }
        }

        public Dictionary<String, DropboxFileSystemItem> Entries
        {
            get;
            private set;
        }

        
        public DateTime? LastDeltaRetrieved
        {
            get
            {
                return _LastDeltaRetrieved;
            }
            set
            {
                this.SetProperty(ref this._LastDeltaRetrieved, value);
            }
        }

        public void MergeDelta(DropboxDelta newDelta)
        {
            this.Cursor = newDelta.Cursor;
            this.Reset = newDelta.Reset;
            this.HasMore = newDelta.HasMore;
            this.LastDeltaRetrieved = newDelta.LastDeltaRetrieved;
            foreach (var item in newDelta.Entries)
            {
                if (Entries.ContainsKey(item.Key))
                    Entries.Remove(item.Key);
                if (item.Value != null)
                    Entries.Add(item.Key, item.Value);
            }
        }

        private void generateNewJsonString()
        {
            originalString = SimpleJson.SimpleJson.SerializeObject(this);
            var sb = new StringBuilder();
            sb.Append("{");
            sb.AppendFormat("\"reset\": {0},", Reset.ToString().ToLower());
            sb.AppendFormat("\"cursor\": \"{0}\",", Cursor);
            sb.AppendFormat("\"has_more\": {0},", HasMore.ToString().ToLower());

            sb.Append("\"entries\":[");
            var firstEntry = true;
            foreach (var item in Entries)
            {
                if (item.Value == null)
                    continue;
                sb.AppendFormat("{2}[\"{0}\",{1}]", item.Key, ((DropboxFileSystemItem)item.Value).ToJSON().Replace("\\\"", "\""), (!firstEntry?", ":""));
                firstEntry = false;
            }
            sb.Append("],");
            if (LastDeltaRetrieved.HasValue)
                sb.AppendFormat("\"dateTimeString\": \"{0:yyyy-MM-dd HH:mm:ss}\"", LastDeltaRetrieved.Value);
            sb.Append("}");
            originalString = sb.ToString();
            Debug.WriteLine("New Delta Original String is:");
            Debug.WriteLine(this.ToString());
        }
    }
}
